package com.internetCafes.spms.web.toolbox.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.utils.entity.page.PageItemDTO;
import com.internetCafes.spms.common.utils.entity.page.PageItemVO;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.web.certificate.entity.CertificateInfo;
import com.internetCafes.spms.web.certificate.service.CertificateInfoService;
import com.internetCafes.spms.web.customer.model.customer.quali.QualiMatchRes;
import com.internetCafes.spms.web.extend.model.EntCertiQualiConf;
import com.internetCafes.spms.web.extend.service.IEntCertiQualiConfService;
import com.internetCafes.spms.web.sys.entity.dto.qualiconf.QualiConfigConfigDto;
import com.internetCafes.spms.web.sys.entity.dto.qualiconf.QualiPageDto;
import com.internetCafes.spms.web.sys.entity.vo.qualiconf.QualiConfVo;
import com.internetCafes.spms.web.sys.entity.vo.qualiconf.QualiConfigCertConfigVo;
import com.internetCafes.spms.web.sys.entity.vo.qualiconf.QualiListVo;
import com.internetCafes.spms.web.sys.entity.vo.qualiconf.QualiPageVo;
import com.internetCafes.spms.web.sys.model.ConfInfo;
import com.internetCafes.spms.web.sys.service.ConfInfoService;
import com.internetCafes.spms.web.toolbox.entity.QualiCertCond;
import com.internetCafes.spms.web.toolbox.entity.QualiConf;
import com.internetCafes.spms.web.toolbox.entity.QualiConfRecord;
import com.internetCafes.spms.web.toolbox.entity.po.QualiCertCondPo;
import com.internetCafes.spms.web.toolbox.entity.po.QualiConfPo;
import com.internetCafes.spms.web.toolbox.entity.vo.quali.SingQualiMatchVo;
import com.internetCafes.spms.web.toolbox.mapper.QualiConfMapper;
import com.internetCafes.spms.web.toolbox.service.IQualiCertCondService;
import com.internetCafes.spms.web.toolbox.service.IQualiConfRecordService;
import com.internetCafes.spms.web.toolbox.service.IQualiConfService;
import org.apache.commons.lang.StringUtils;
import org.nlpcn.commons.lang.util.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 资质信息配置 服务实现类
 * </p>
 *
 * @author Zj
 * @since 2021-06-13
 */
@Service
public class QualiConfServiceImpl extends ServiceImpl<QualiConfMapper, QualiConf> implements IQualiConfService {

    @Autowired
    private IQualiConfRecordService iQualiConfRecordService;
    @Autowired
    private IQualiCertCondService iQualiCertCondService;
    @Autowired
    private ConfInfoService confInfoService;
    @Autowired
    private CertificateInfoService certificateInfoService;
    @Autowired
    private IEntCertiQualiConfService iEntCertiQualiConfService;


    @Override
    public List<QualiConfPo> qualiConfPoList() {
        return baseMapper.qualiConfPoList();
    }

    @Override
    public Map<String, QualiMatchRes> qualiMatchMap() {
        List<QualiConf> qualiPoList = list();
        return qualiPoList.stream()
                .map(qualiPo -> {
                    QualiMatchRes res = new QualiMatchRes()
                            .setId(qualiPo.getId());
                    res.setName(qualiPo.getQualiCode(), qualiPo.getGradeTag());
                    return res;
                })
                .collect(Collectors.toMap(QualiMatchRes::getName, Function.identity()));
    }

    /**
     * 资质全部匹配并进行分页
     *
     * @param dto
     */
    @Override
    public PageItemVO<QualiPageVo> matchAllAndPage(PageItemDTO<QualiPageDto> dto) {
        QualiPageDto qualiPageDto = dto.getConditions();
        if (ObjectUtils.isEmpty(qualiPageDto.getTypeTag())) {
            throw new RRException("参数错误");
        }
        Integer pageSize = dto.getPageSize();
        Integer pageNum = dto.getPageNum();
        List<SingQualiMatchVo> singQualiMatchVos = batchQualiMatch(qualiPageDto.getTypeTag());
        PageItemVO<QualiPageVo> pageItemVO = new PageItemVO<>();

        List<QualiPageVo> qualiPageVos = singQualiMatchVos.stream()
                .map(singQualiMatchVo -> {
                    QualiPageVo qualiPageVo = new QualiPageVo();
                    BeanUtils.copyProperties(singQualiMatchVo, qualiPageVo);
                    qualiPageVo.setId(singQualiMatchVo.getId());
                    qualiPageVo.setQualiName(singQualiMatchVo.getQualiCode());
                    return qualiPageVo;
                })
                .collect(Collectors.toList());

        pageItemVO.setTotal(qualiPageVos.size());
        pageItemVO.setCurrent(pageNum);
        pageItemVO.setSize(pageSize);
        pageItemVO.setPages(qualiPageVos.size() % pageSize == 0 ? qualiPageVos.size() / pageSize : (qualiPageVos.size() / pageSize) + 1);
        List<QualiPageVo> subList = new ArrayList<>();
        if (qualiPageVos.size() > 0) {
            subList = qualiPageVos.subList((pageNum - 1) * pageSize,
                    ((pageNum - 1) * pageSize + pageSize) > qualiPageVos.size() ?
                            qualiPageVos.size() - 1 : ((pageNum - 1) * pageSize + pageSize));
        }
        pageItemVO.setRecords(subList);
        return pageItemVO;
    }

    /**
     * 匹配配置的资质信息
     */
    @Override
    public List<SingQualiMatchVo> matchCond(Long certId) {
        List<SingQualiMatchVo> singQualiMatchVos = new ArrayList<>();
        QueryWrapper<EntCertiQualiConf> entCertiQualiConfWrapper = new QueryWrapper<>();
        entCertiQualiConfWrapper.eq("certificate_id", certId);
        List<EntCertiQualiConf> entCertiQualiConfs = iEntCertiQualiConfService.list(entCertiQualiConfWrapper);
        List<Long> confInfoIds = entCertiQualiConfs.stream()
                .map(EntCertiQualiConf::getConfId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(confInfoIds)) {
            return singQualiMatchVos;
        }
        List<ConfInfo> confInfos = confInfoService.queryByIds(confInfoIds);
        List<String> confInfoNames = confInfos.stream()
                .map(ConfInfo::getName)
                .collect(Collectors.toList());

        QueryWrapper<QualiCertCond> certQuery = new QueryWrapper<QualiCertCond>()
                .in("xqc.quali_code", confInfoNames).eq("xqc.status_flag", 1);
        List<QualiCertCondPo> certList = iQualiCertCondService.getCertList(certQuery);

        Map<String, Long> assoMap = confInfos.stream().collect(Collectors.toMap(ConfInfo::getName, ConfInfo::getId));
        Map<Long, List<EntCertiQualiConf>> qualiConfCollect = entCertiQualiConfs.stream()
                .collect(Collectors.groupingBy(EntCertiQualiConf::getConfId));

        Map<Long, List<QualiCertCondPo>> qualiCertConds = certList.stream()
                .filter(cert -> {
                    Long id = assoMap.get(cert.getQualiCode());
                    List<Integer> levels = qualiConfCollect.get(id).stream()
                            .map(EntCertiQualiConf::getLevel).collect(Collectors.toList());

                    return levels.contains(cert.getGradeTag());
                }).collect(Collectors.groupingBy(QualiCertCondPo::getQualiId));
        List<CertificateInfo> allHandlerCerts = certificateInfoService.getAllHandlerCerts();
        Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();
        Map<String, Map<String, List<ConfInfo>>> professionGroup = confInfoService.groupCertProfession();

        // 获取所需资质项
        List<Long> qualiIds = certList.stream()
                .map(QualiCertCondPo::getQualiId)
                .collect(Collectors.toList());
        Map<Long, QualiConf> qualiGroupById = new HashMap<>();
        if (CollectionUtil.isNotEmpty(qualiIds)) {
            qualiGroupById = listByIds(qualiIds).stream()
                    .collect(Collectors.toMap(QualiConf::getId, qualiConf -> qualiConf));
        }

        for (Map.Entry<Long, List<QualiCertCondPo>> certEntry : qualiCertConds.entrySet()) {
            singQualiMatchVos.add(singQualiMatchVo(qualiGroupById.get(certEntry.getKey()), certEntry.getValue(), allHandlerCerts, certTypeGroup, professionGroup));
        }

        return singQualiMatchVos;
    }

    /**
     * 一件匹配一种类型的资质
     */
    @Override
    public List<SingQualiMatchVo> batchQualiMatch(Integer typeTag) {

        QueryWrapper<QualiCertCond> certConds = new QueryWrapper<QualiCertCond>()
                .eq("xqc.type_tag", typeTag)
                .eq("xqc.status_flag", 1);
        List<QualiCertCondPo> certList = iQualiCertCondService.getCertList(certConds);
        List<CertificateInfo> allHandlerCerts = certificateInfoService.getAllHandlerCerts();
        Map<Long, List<QualiCertCondPo>> qualiCertConds = certList.stream()
                .collect(Collectors.groupingBy(QualiCertCondPo::getQualiId));
        Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();
        Map<String, Map<String, List<ConfInfo>>> professionGroup = confInfoService.groupCertProfession();
        List<SingQualiMatchVo> singQualiMatchVos = new ArrayList<>();

        // 获取所需资质项
        List<Long> qualiIds = certList.stream()
                .map(QualiCertCondPo::getQualiId)
                .collect(Collectors.toList());
        Map<Long, QualiConf> qualiGroupById = listByIds(qualiIds).stream()
                .collect(Collectors.toMap(QualiConf::getId, qualiConf -> qualiConf));
        SingQualiMatchVo singQualiMatchVo;
        for (Map.Entry<Long, List<QualiCertCondPo>> certEntry : qualiCertConds.entrySet()) {
            singQualiMatchVo = singQualiMatchVo(qualiGroupById.get(certEntry.getKey()), certEntry.getValue(), allHandlerCerts, certTypeGroup, professionGroup);
            if (singQualiMatchVo.getResultTag()) {
                singQualiMatchVos.add(singQualiMatchVo);
            }
        }
        return singQualiMatchVos;
    }

    /**
     * @param qualiConfId 资质条件id
     * @return
     */
    @Override
    public SingQualiMatchVo singQualiMatch(Long qualiConfId) {
        QualiConf qualiConf = getById(qualiConfId);
        if (ObjectUtils.isNull(qualiConf)) {
            throw new RRException("数据不存在");
        }
        List<QualiCertCondPo> certList = iQualiCertCondService.getCertListByQualiId(qualiConfId);
        List<CertificateInfo> allHandlerCerts = certificateInfoService.getAllHandlerCerts();
        Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();
        Map<String, Map<String, List<ConfInfo>>> professionGroup = confInfoService.groupCertProfession();
        SingQualiMatchVo result = singQualiMatchVo(qualiConf, certList, allHandlerCerts, certTypeGroup, professionGroup);
        return result;
    }

    /**
     * 单条资质匹配
     *
     * @param certList
     * @param allHandlerCerts
     * @return
     */
    @Override
    public SingQualiMatchVo singQualiMatchVo(QualiConf qualiConf, List<QualiCertCondPo> certList, List<CertificateInfo> allHandlerCerts, Map<String, List<ConfInfo>> certTypeGroup, Map<String, Map<String, List<ConfInfo>>> professionGroup) {
        /**
         * 单条资质匹配逻辑说明
         * 1-获取所有证书数量条件信息，并进行分组处理
         *      1.1-分别以资质id，条件记录id，条件分组id，条件分组层级序号 进行分级
         * 2-获取企业所拥有得证书列表，进行分组
         *      2.1-分别以类型、类别、专业、状态进行分组
         * 3-遍历条件信息进行匹配封装
         *      3.1-遍历资质id/遍历条件id信息，获取保存的条件信息
         *      3.2-遍历分组和分组层级、获取分组或或者且得条件
         *      3.3-证书数量条件满足判定，封装记录 过期不算
         * 4-将数据封装回实体类，返回
         */

        Map<Long, List<QualiCertCondPo>> qualiCertGroup = certList.stream()
                .collect(Collectors.groupingBy(QualiCertCondPo::getRecordId));

        Map<String, Map<String, Map<String, List<CertificateInfo>>>> certsGroup = allHandlerCerts.stream()
                .filter(cert -> !ObjectUtils.isNull(cert.getpIdType())
                        && !ObjectUtils.isNull(cert.getIdType())
                        && !ObjectUtils.isNull(cert.getProfession()))
                .collect(Collectors.groupingBy(CertificateInfo::getpIdType,
                        Collectors.groupingBy(CertificateInfo::getIdType,
                                Collectors.groupingBy(CertificateInfo::getProfession))));

        // 获取当前资质证书列表
        /*Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();
        Map<String, Map<String, List<ConfInfo>>> professionGroup = confInfoService.groupCertProfession();*/
        Date currentTime = new Date();

        // 初始化复用变量准备
        List<QualiCertCondPo> certConds;
        String singleNeedCertDetail;
        Boolean resultFlag = true;
        Boolean singleFlag;
        String singleHandleCertDetail;
        String singleCertStatus;
        String singleExplains;
        String needCertDetail;
        String handleCertDetail;
        List<String> condComment;
        List<String> hanldeComment;
        List<String> certStatusComment;
        Integer handleAmount;
        Boolean handleCompleteFlag;
        List<SingQualiMatchVo.CondMatchResult> condMatchResultList = new ArrayList<>();
        for (Map.Entry<Long, List<QualiCertCondPo>> qualiCertGroupByRecordId : qualiCertGroup.entrySet()) {
            // 这里一次循环就是一条记录 目前此模块结构已经完善，并能通过条件列表进行 并 操作 后续有需要需要修改逻辑
            certConds = qualiCertGroupByRecordId.getValue();
            singleExplains = certConds.get(0).getExplains();
            Integer condTag = certConds.get(0).getCondTag();
            // 拼接已有证书情况
            condComment = new ArrayList<>();
            // 已有证书内容拼接
            singleFlag = false;
            hanldeComment = new ArrayList<>();
            certStatusComment = new ArrayList<>();
            Map<String, Integer> statusMap = new HashMap<>();
            for (QualiCertCondPo qualiCertCondPo : certConds) {
                // 专业条件数据拼接
                needCertDetail = "";
                if (StringUtils.isNotBlank(qualiCertCondPo.getProfessionCode())) {
                    needCertDetail = qualiCertCondPo.getProfessionCode() + needCertDetail;
                }
                if (StringUtils.isNotBlank(qualiCertCondPo.getCategoryCode())) {
                    needCertDetail = qualiCertCondPo.getCategoryCode() + needCertDetail;
                }
                needCertDetail = certTypeGroup.get(qualiCertCondPo.getTypeCode()).get(0).getName()
                        + needCertDetail + qualiCertCondPo.getAmount() + "本";
                if (qualiCertCondPo.getCompleteFlag().equals(1)) {
                    needCertDetail = needCertDetail + "，专业齐全";
                }
                condComment.add(needCertDetail);

                // 开始判断是否条件满足 初始化默认值
                Integer completeFlag = qualiCertCondPo.getCompleteFlag();
                handleAmount = 0;
                handleCompleteFlag = true;
                // 到专业
                if (StringUtils.isNotBlank(qualiCertCondPo.getProfessionCode())) {
                    handleCertDetail = qualiCertCondPo.getProfessionCode();
                    if (CollectionUtils.isEmpty(certsGroup.get(qualiCertCondPo.getTypeCode()))) {
                        // 无证书，不合格
                    } else {
                        if (CollectionUtils.isEmpty(certsGroup
                                .get(qualiCertCondPo.getTypeCode())
                                .get(qualiCertCondPo.getCategoryCode()))) {
                            // 无证书，不符合标准
                        } else {
                            if (CollectionUtils.isEmpty(certsGroup
                                    .get(qualiCertCondPo.getTypeCode())
                                    .get(qualiCertCondPo.getCategoryCode())
                                    .get(qualiCertCondPo.getProfessionCode()))) {
                                // 无证书，不符合标准
                            } else {
                                List<CertificateInfo> certificateInfos = certsGroup
                                        .get(qualiCertCondPo.getTypeCode())
                                        .get(qualiCertCondPo.getCategoryCode())
                                        .get(qualiCertCondPo.getProfessionCode());
                                // 未过期的证书
                                List<CertificateInfo> collectUnValidity = certificateInfos.stream()
                                        .filter(certificateInfo ->
                                                certificateInfo.getValidityEndTime() == null || currentTime.before(certificateInfo.getValidityEndTime()))
                                        .collect(Collectors.toList());
                                // 证书状态数量计算
                                int validityAmount = certificateInfos.size() - collectUnValidity.size();
                                Map<Integer, List<CertificateInfo>> statusGroup = collectUnValidity.stream()
                                        .collect(Collectors.groupingBy(CertificateInfo::getStatus));

                                for (Map.Entry<Integer, List<CertificateInfo>> statusEntry : statusGroup.entrySet()) {
                                    String statusName = CommonConstants.CertificateStatus.getDescr(statusEntry.getKey());
                                    if (!statusMap.containsKey(statusName)) {
                                        statusMap.put(statusName, statusEntry.getValue().size());
                                    } else {
                                        Integer amountResource = statusMap.get(statusName);
                                        statusMap.put(statusName, amountResource + statusEntry.getValue().size());
                                    }
                                }
                                if (validityAmount > 0) {
                                    if (!statusMap.containsKey("过期")) {
                                        statusMap.put("过期", validityAmount);
                                    } else {
                                        Integer amountResource = statusMap.get("过期");
                                        statusMap.put("过期", amountResource + validityAmount);
                                    }
                                }
                                // 如果持有未过期证书数量大于等于需要证书数量
                                if ((handleAmount = collectUnValidity.size()) >= qualiCertCondPo.getAmount()) {
                                    singleFlag = true;
                                }
                            }
                        }
                    }
                } else if (StringUtils.isNotBlank(qualiCertCondPo.getCategoryCode())) {
                    handleCertDetail = qualiCertCondPo.getCategoryCode();
                    if (CollectionUtils.isEmpty(certsGroup.get(qualiCertCondPo.getTypeCode()))) {
                        // 无证书 ， 不符合标准
                    } else {
                        if (CollectionUtils.isEmpty(certsGroup
                                .get(qualiCertCondPo.getTypeCode())
                                .get(qualiCertCondPo.getCategoryCode()))) {
                            // 无证书，不符合标准
                        } else {
                            // 计算证书数量
                            Map<String, List<CertificateInfo>> groupByProfession = certsGroup
                                    .get(qualiCertCondPo.getTypeCode())
                                    .get(qualiCertCondPo.getCategoryCode());
                            int totalAmount;
                            int unValidityAmount;

                            for (Map.Entry<String, List<CertificateInfo>> professionEntry : groupByProfession.entrySet()) {
                                List<CertificateInfo> certificateValue = professionEntry.getValue();
                                // 证书未过期
                                List<CertificateInfo> unValidityCerts = professionEntry
                                        .getValue().stream().filter(certificateInfo ->
                                                certificateInfo.getValidityEndTime() == null
                                                        || currentTime.before(certificateInfo.getValidityEndTime()))
                                        .collect(Collectors.toList());

                                Map<Integer, List<CertificateInfo>> groupByStatus = unValidityCerts
                                        .stream().collect(Collectors.groupingBy(CertificateInfo::getStatus));
                                List<String> professions = unValidityCerts.stream().map(CertificateInfo::getProfession).collect(Collectors.toList());

                                // 如果专业齐全
                                if (completeFlag.equals(1)) {
                                    Map<String, List<ConfInfo>> typeGroup = professionGroup.get(qualiCertCondPo.getTypeCode());
                                    if (CollectionUtils.isNotEmpty(typeGroup)) {
                                        List<ConfInfo> categoryGroup = typeGroup.get(qualiCertCondPo.getCategoryCode());
                                        if (CollectionUtils.isNotEmpty(categoryGroup)) {
                                            for (ConfInfo confInfo : categoryGroup) {
                                                if (!professions.contains(confInfo.getName())) {
                                                    handleCompleteFlag = false;
                                                }
                                                break;
                                            }
                                        }
                                    }
                                }

                                for (Map.Entry<Integer, List<CertificateInfo>> statusEntry : groupByStatus.entrySet()) {
                                    Integer status = statusEntry.getKey();
                                    String statusName = CommonConstants.CertificateStatus.getDescr(status);
                                    if (!statusMap.containsKey(statusName)) {
                                        statusMap.put(statusName, statusEntry.getValue().size());
                                    } else {
                                        Integer amountResource = statusMap.get(statusName);
                                        statusMap.put(statusName, amountResource + statusEntry.getValue().size());
                                    }
                                }

                                totalAmount = certificateValue.size();
                                unValidityAmount = unValidityCerts.size();

                                // 计算过期整数数量
                                if ((totalAmount - unValidityAmount) > 0) {
                                    if (!statusMap.containsKey("过期")) {
                                        statusMap.put("过期", totalAmount - unValidityAmount);
                                    } else {
                                        Integer amountResource = statusMap.get("过期");
                                        statusMap.put("过期", amountResource + totalAmount - unValidityAmount);
                                    }
                                }
                                handleAmount = handleAmount + unValidityAmount;
                            }
                        }
                    }
                } else {
                    handleCertDetail = certTypeGroup.get(qualiCertCondPo.getTypeCode()).get(0).getName();
                    if (CollectionUtils.isEmpty(certsGroup.get(qualiCertCondPo.getTypeCode()))) {
                        // 无证书 ， 不符合标准
                    } else {
                        // 证书数量
                        Map<String, Map<String, List<CertificateInfo>>> groupByTypeCode = certsGroup.get(qualiCertCondPo.getTypeCode());
                        for (Map.Entry<String, Map<String, List<CertificateInfo>>> typeCodeGroup : groupByTypeCode.entrySet()) {
                            Map<String, List<CertificateInfo>> typeCodeGroupValue = typeCodeGroup.getValue();
                            int totalAmount;
                            int unValidityAmount;
                            for (Map.Entry<String, List<CertificateInfo>> groupByCategoryCode : typeCodeGroupValue.entrySet()) {
                                List<CertificateInfo> certificateValue = groupByCategoryCode.getValue();
                                List<CertificateInfo> unValidityCerts = certificateValue.stream()
                                        .filter(certificateInfo ->
                                                certificateInfo.getValidityEndTime() == null
                                                        || currentTime.before(certificateInfo.getValidityEndTime()))
                                        .collect(Collectors.toList());
                                List<String> professions = unValidityCerts.stream().map(CertificateInfo::getProfession).collect(Collectors.toList());

                                // 证书齐全标签
                                if (completeFlag.equals(1)) {
                                    Map<String, List<ConfInfo>> typeGroup = professionGroup.get(qualiCertCondPo.getTypeCode());
                                    if (CollectionUtils.isNotEmpty(typeGroup)) {
                                        for (Map.Entry<String, List<ConfInfo>> typeGroupEntry : typeGroup.entrySet()) {
                                            if (handleCompleteFlag) {
                                                for (ConfInfo confInfo : typeGroupEntry.getValue()) {
                                                    if (!professions.contains(confInfo.getName())) {
                                                        handleCompleteFlag = false;
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                Map<Integer, List<CertificateInfo>> groupByStatus = unValidityCerts
                                        .stream().collect(Collectors.groupingBy(CertificateInfo::getStatus));

                                for (Map.Entry<Integer, List<CertificateInfo>> statusEntry : groupByStatus.entrySet()) {
                                    Integer status = statusEntry.getKey();
                                    String statusName = CommonConstants.CertificateStatus.getDescr(status);
                                    if (!statusMap.containsKey(statusName)) {
                                        statusMap.put(statusName, statusEntry.getValue().size());
                                    } else {
                                        Integer amountResource = statusMap.get(statusName);
                                        statusMap.put(statusName, amountResource + statusEntry.getValue().size());
                                    }
                                }
                                totalAmount = certificateValue.size();
                                unValidityAmount = unValidityCerts.size();
                                // 计算过期整数数量
                                if ((totalAmount - unValidityAmount) > 0) {
                                    if (!statusMap.containsKey("过期")) {
                                        statusMap.put("过期", totalAmount - unValidityAmount);
                                    } else {
                                        Integer amountResource = statusMap.get("过期");
                                        statusMap.put("过期", amountResource + totalAmount - unValidityAmount);
                                    }
                                }
                                handleAmount = handleAmount + unValidityAmount;
                            }
                        }
                    }
                }
                handleCertDetail = handleCertDetail + handleAmount + "本";
                if (handleAmount > qualiCertCondPo.getAmount()) {
                    if (!completeFlag.equals(1)) {
                        singleFlag = true;
                    } else {
                        if (handleCompleteFlag) {
                            singleFlag = true;
                        } else {
                            handleCertDetail = handleCertDetail + "专业不齐全";
                        }
                    }
                }
                if (StringUtils.isNotBlank(handleCertDetail)) {
                    hanldeComment.add(handleCertDetail);
                }
            }
            // 单条记录需要得证书条件
            singleNeedCertDetail = condComment.stream().collect(Collectors.joining(condTag.equals(1) ? "并" : "或"));
            // 单条记录的持有证书字段
            singleHandleCertDetail = String.join("和", hanldeComment);
            // 证书状态封装成文本
            if (CollectionUtils.isNotEmpty(statusMap)) {
                for (Map.Entry<String, Integer> statusEntry : statusMap.entrySet()) {
                    if (statusEntry.getKey().equals("过期")) {
                        continue;
                    }
                    certStatusComment.add(statusEntry.getKey() + statusEntry.getValue() + "本");
                }
                if (statusMap.containsKey("过期")) {
                    certStatusComment.add("过期" + statusMap.get("过期") + "本");
                }
                singleCertStatus = String.join(",", certStatusComment);
            } else {
                singleCertStatus = "暂无证书";
            }
            // 如果有一条记录不满足条件 对整个记录置为空
            if (!singleFlag) {
                resultFlag = false;
            }
            // 单条数据添加到列表中
            condMatchResultList.add(new SingQualiMatchVo.CondMatchResult(
                    qualiCertGroupByRecordId.getKey(), singleFlag,
                    singleNeedCertDetail, singleHandleCertDetail,
                    singleCertStatus, singleExplains));
        }
        String needCert = condMatchResultList.stream()
                .map(SingQualiMatchVo.CondMatchResult::getNeedCertDetail)
                .collect(Collectors.joining(";"));

        return new SingQualiMatchVo(qualiConf.getId(),
                resultFlag, qualiConf.getArticleContent(), qualiConf.getGradeTag(),
                needCert, qualiConf.getQualiCode(), condMatchResultList);
    }

    /**
     * 资质查询列表
     *
     * @param dto 请求参数
     * @return 结果
     */
    @Override
    public PageItemVO<QualiPageVo> page(PageItemDTO<QualiPageDto> dto) {
        Page<QualiConf> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        QualiPageDto conditions = dto.getConditions();
        QueryWrapper<QualiConf> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtil.isNotBlank(conditions.getQualiName()), "quali_code", conditions.getQualiName())
                .eq(ObjectUtils.isNotNull(conditions.getTypeTag()), "type_tag", conditions.getTypeTag())
                .eq(ObjectUtils.isNotNull(conditions.getGradeTag()), "grade_tag", conditions.getGradeTag())
                .eq(ObjectUtils.isNotNull(conditions.getStatusFlag()), "status_flag", conditions.getStatusFlag());
        // 排序
        if (StringUtil.isNotBlank(dto.getOrderBy())) {
            if ("desc".equals(dto.getInOrder())) {
                queryWrapper
                        .orderByDesc(com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(dto.getOrderBy()));
            } else {
                queryWrapper
                        .orderByAsc(com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(dto.getOrderBy()));
            }
        } else {
            queryWrapper.orderByDesc("id");
        }
        IPage<QualiConf> pageResult = baseMapper.selectPage(page, queryWrapper);

        // 分页数据封装
        PageItemVO<QualiPageVo> result = new PageItemVO<>();
        BeanUtils.copyProperties(pageResult, result);
        List<QualiConf> records = pageResult.getRecords();

        List<Long> qualiIds = records.stream().map(QualiConf::getId).collect(Collectors.toList());
        List<QualiCertCondPo> certList = new ArrayList<>();
        // 显示所需证书信息文本数据封装
        if (CollectionUtils.isNotEmpty(qualiIds)) {

            certList = iQualiCertCondService.getCertList(new QueryWrapper<QualiCertCond>().in("xqcr.quali_conf_id", qualiIds));
        }

        Map<Long, Map<Long, Map<Long, List<QualiCertCondPo>>>> certsGroup = certList.stream()
                .collect(Collectors.groupingBy(QualiCertCondPo::getQualiConfId,
                        Collectors.groupingBy(QualiCertCondPo::getRecordId,
                                Collectors.groupingBy(QualiCertCondPo::getGroupId))));


        List<QualiPageVo> qualiPageVos = records.stream()
                .map(record -> {
                    QualiPageVo qualiPageVo = new QualiPageVo();
                    BeanUtils.copyProperties(record, qualiPageVo);
                    qualiPageVo.setQualiName(record.getQualiCode());

                    qualiPageVo.setNeedCert(allCertCond(record.getId(), certsGroup));
                    return qualiPageVo;
                })
                .collect(Collectors.toList());
        result.setRecords(qualiPageVos);
        return result;
    }

    /**
     * 拼接全部信息
     *
     * @param qualiId     资质id
     * @param certsGroups 证书分组
     * @return 拼接信息
     */
    private String allCertCond(Long qualiId, Map<Long, Map<Long, Map<Long, List<QualiCertCondPo>>>> certsGroups) {
        Map<Long, Map<Long, List<QualiCertCondPo>>> certsGroupByRecordIdAndGroupId = certsGroups.get(qualiId);
        if (CollectionUtils.isEmpty(certsGroupByRecordIdAndGroupId)) {
            return "";
        }
        Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();
        List<String> contents = new ArrayList<>();
        for (Map.Entry<Long, Map<Long, List<QualiCertCondPo>>> certsGroupByGroupId : certsGroupByRecordIdAndGroupId.entrySet()) {
            Map<Long, List<QualiCertCondPo>> value = certsGroupByGroupId.getValue();
            for (Map.Entry<Long, List<QualiCertCondPo>> certsGroup : value.entrySet()) {
                List<QualiCertCondPo> certs = certsGroup.getValue();
                List<QualiCertCond> certInfos = certs.stream()
                        .map(cert -> {
                            QualiCertCond qualiCertCond = new QualiCertCond();
                            BeanUtils.copyProperties(cert, qualiCertCond);
                            return qualiCertCond;
                        })
                        .collect(Collectors.toList());
                String recordContent = iQualiCertCondService.contentSplicing(certInfos, certs.get(0).getCondTag().equals(1) ? "并" : "或", certTypeGroup);
                contents.add(recordContent);
            }

        }
        return StringUtil.joiner(contents, ";");

    }

    /**
     * 资质列表
     *
     * @return 结果
     */
    @Override
    public List<QualiListVo> qualiList() {
        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CONF_QUALIFICATION_GRADE_TYPE);
        List<ConfInfo> confInfos = confInfoService.query(params);
        List<QualiListVo> qualiListVos = confInfos.stream()
                .map(confInfo -> {
                    QualiListVo qualiListVo = new QualiListVo();

                    Map<Integer, String> levels = CommonConstants.NewQualificationLevels.getLevels(confInfo.getName());
                    qualiListVo.setCode(confInfo.getName());
                    qualiListVo.setName(confInfo.getName());
                    for (Map.Entry<Integer, String> level : levels.entrySet()) {
                        qualiListVo.getLevels().add(new QualiListVo.Level(level.getKey(), level.getValue()));
                    }

                    return qualiListVo;
                })
                .collect(Collectors.toList());
        return qualiListVos;
    }

    /**
     * 删除资质信息
     *
     * @param id 资质id
     */
    @Override
    public void delete(Long id) {
        QualiConf qualiConfPo = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(qualiConfPo)) {
            throw new RRException("记录不存在");
        }

        deleteAdditionalInfoOfQuali(id);

        baseMapper.deleteById(id);
    }

    /**
     * 删除资质信息附带信息
     *
     * @param qualiConfId 资质信息id
     */
    private void deleteAdditionalInfoOfQuali(Long qualiConfId) {
        // 记录列表删除
        List<QualiConfRecord> qualiConfRecords = iQualiConfRecordService.list(
                new QueryWrapper<>(new QualiConfRecord().setQualiConfId(qualiConfId)));
        iQualiConfRecordService.remove(new QueryWrapper<>(new QualiConfRecord().setQualiConfId(qualiConfId)));

        if (CollectionUtils.isNotEmpty(qualiConfRecords)) {
            List<Long> recordIds = qualiConfRecords.stream()
                    .map(QualiConfRecord::getId)
                    .collect(Collectors.toList());

            iQualiCertCondService.deleteGroupByRecordIds(recordIds);
        }
    }

    /**
     * 删除资质信息附带信息
     *
     * @param qualiConfId 资质信息id
     */
    private void deleteAdditionalOtherInfoOfQuali(Long qualiConfId, List<Long> recordIds) {
        QueryWrapper<QualiConfRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.eq("quali_conf_id", qualiConfId)
                .notIn(CollectionUtils.isNotEmpty(recordIds), "id", recordIds);
        // 记录列表删除
        List<QualiConfRecord> qualiConfRecords = iQualiConfRecordService.list(recordQueryWrapper);
        iQualiConfRecordService.remove(recordQueryWrapper);

        if (CollectionUtils.isNotEmpty(qualiConfRecords)) {
            List<Long> recordId = qualiConfRecords.stream()
                    .map(QualiConfRecord::getId)
                    .collect(Collectors.toList());

            iQualiCertCondService.deleteGroupByRecordIds(recordId);
        }
    }

    /**
     * 自制配置编辑
     *
     * @param dto 请求参数
     */
    @Override
    public void edit(QualiConfigConfigDto dto) {

        QualiConf qualiConfPo = baseMapper.selectById(dto.getId());
        if (ObjectUtils.isEmpty(qualiConfPo)) {
            throw new RRException("记录不存在");
        }

        QualiConf qualiConfDo = new QualiConf();
        BeanUtils.copyProperties(dto, qualiConfDo);
        baseMapper.updateById(qualiConfDo);

        deleteAdditionalOtherInfoOfQuali(dto.getId(), dto.getCertCondIds());

        if (CollectionUtils.isNotEmpty(dto.getCertCondIds())) {
            UpdateWrapper<QualiConfRecord> qualiConfRecordUpdateWrapper = new UpdateWrapper<>();
            qualiConfRecordUpdateWrapper.in("id", dto.getCertCondIds())
                    .set("quali_conf_id", qualiConfDo.getId());
            iQualiConfRecordService.update(qualiConfRecordUpdateWrapper);
        }
    }

    /**
     * 获取资质编辑信息
     *
     * @param id 资质id
     * @return 结果
     */
    @Override
    public QualiConfVo toEdit(Long id) {
        QualiConf qualiConfPo = baseMapper.selectById(id);

        if (ObjectUtils.isEmpty(qualiConfPo)) {
            throw new RRException("数据不存在");
        }

        QualiConfVo qualiConfVo = new QualiConfVo();
        BeanUtils.copyProperties(qualiConfPo, qualiConfVo);

        List<QualiConfRecord> qualiConfRecords = iQualiConfRecordService.list(
                new QueryWrapper<>(
                        new QualiConfRecord().setQualiConfId(id)));
        // 获取当前资质证书列表
        List<QualiCertCondPo> certList = iQualiCertCondService.getCertListByQualiId(id);
        Map<Long, Map<Long, List<QualiCertCondPo>>> certGroupByRecordIdAndGroupId = certList.stream()
                .collect(Collectors.groupingBy(QualiCertCondPo::getRecordId,
                        Collectors.groupingBy(QualiCertCondPo::getGroupId)));

        Map<String, List<ConfInfo>> certTypeGroup = confInfoService.certTypeGroup();

        List<QualiConfigCertConfigVo> qualiConfigCertConfigVos = qualiConfRecords.stream()
                .map(record -> {
                    QualiConfigCertConfigVo recordVo = new QualiConfigCertConfigVo();
                    BeanUtils.copyProperties(record, recordVo);
                    Map<Long, List<QualiCertCondPo>> certGroupByGroupId = certGroupByRecordIdAndGroupId.get(record.getId());
                    if (CollectionUtils.isNotEmpty(certGroupByGroupId)) {
                        List<String> content = new ArrayList<>();
                        List<QualiConfigCertConfigVo.CertInfo> certInfos = new ArrayList<>();
                        for (Map.Entry<Long, List<QualiCertCondPo>> certGroupEntry : certGroupByGroupId.entrySet()) {
                            // 目前只有一个组的概念后期如需要新增组需要修改
                            List<QualiCertCondPo> valueList = certGroupEntry.getValue();
                            List<QualiCertCond> qualiCertConds = valueList.stream()
                                    .map(valueTemp -> {
                                        QualiCertCond qualiCertCond = new QualiCertCond();
                                        BeanUtils.copyProperties(valueTemp, qualiCertCond);
                                        return qualiCertCond;
                                    })
                                    .collect(Collectors.toList());
                            recordVo.setExplain(certGroupEntry.getValue().get(0).getExplains());
                            recordVo.setCondTag(certGroupEntry.getValue().get(0).getCondTag());
                            content.add(iQualiCertCondService.contentSplicing(qualiCertConds, certGroupEntry.getValue().get(0).getCondTag().equals(1) ? "并" : "或", certTypeGroup));
                            List<QualiConfigCertConfigVo.CertInfo> certInfosTemp = qualiCertConds.stream()
                                    .map(certCond -> {
                                        QualiConfigCertConfigVo.CertInfo certInfo = new QualiConfigCertConfigVo.CertInfo();
                                        BeanUtils.copyProperties(certCond, certInfo);
                                        return certInfo;
                                    })
                                    .collect(Collectors.toList());
                            certInfos.addAll(certInfosTemp);
                        }
                        recordVo.setContent(StringUtil.joiner(content, ","));
                        recordVo.setCertInfos(certInfos);

                    }
                    return recordVo;
                })
                .collect(Collectors.toList());
        qualiConfVo.setCertConds(qualiConfigCertConfigVos);

        return qualiConfVo;
    }

    /**
     * 资质新增
     *
     * @param dto 请求参数
     */
    @Override
    public void add(QualiConfigConfigDto dto) {

        List<QualiConf> qualiConfs = baseMapper.selectList(
                new QueryWrapper<>(
                        new QualiConf()
                                .setQualiCode(dto.getQualiCode())
                                .setGradeTag(dto.getGradeTag())));
        if (CollectionUtils.isNotEmpty(qualiConfs)) {
            throw new RRException("资质配置已存在");
        }

        QualiConf qualiConfDo = new QualiConf();
        BeanUtils.copyProperties(dto, qualiConfDo);
        baseMapper.insert(qualiConfDo);

        if (CollectionUtils.isNotEmpty(dto.getCertCondIds())) {
            UpdateWrapper<QualiConfRecord> qualiConfRecordUpdateWrapper = new UpdateWrapper<>();
            qualiConfRecordUpdateWrapper.in("id", dto.getCertCondIds())
                    .set("quali_conf_id", qualiConfDo.getId());
            iQualiConfRecordService.update(qualiConfRecordUpdateWrapper);
        }
    }
}
